#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include "unit_test.h"
#include "pcie_mem.h"
#include "can_test.h"
#include "canfd_test.h"
#include "do_test.h"
#include "di_test.h"
#include "ao_test.h"
#include "pi_test.h"
#include "ai_test.h"
#include "pt100_test.h"

#define TEST_UNIT_NUM   (1 + 8)     /* 测试单元数量 */

struct test_unit_t {
    uint8_t id;
    char name[32];
    char text[128];
    int (*unit_test)(int argc, char *argv[]);
};

struct test_unit_t test_unit[TEST_UNIT_NUM];

static void init_test_unit(struct test_unit_t *test_unit) {
    test_unit[0] = (struct test_unit_t){0,  "null",     "0. 退出程序",      NULL};
    test_unit[1] = (struct test_unit_t){1,  "can",      "1. CAN 测试",      can_test};
    test_unit[2] = (struct test_unit_t){2,  "canfd",    "2. CANFD 测试",    canfd_test};
    test_unit[3] = (struct test_unit_t){3,  "do",       "3. DO 测试",       do_test};
    test_unit[4] = (struct test_unit_t){4,  "di",       "4. DI 测试",       di_test};
    test_unit[5] = (struct test_unit_t){5,  "ao",       "5. AO 测试",       ao_test};
    test_unit[6] = (struct test_unit_t){6,  "pi",       "6. PI 测试",       pi_test};
    test_unit[7] = (struct test_unit_t){7,  "ai",       "7. AI 测试",       ai_test};
    test_unit[8] = (struct test_unit_t){8,  "pt100",    "8. PT100 测试",    pt100_test};
}

volatile sig_atomic_t exit_flag = 0;
void handle_sigint(int sig) {
    (void)sig;
    exit_flag = 1;
}

static void usage(void)
{
    uint8_t i = 0;

    printf("用法: ./unit_test [测试单元]\n");
    printf("测试单元:\n");
    for (i = 0; i < TEST_UNIT_NUM; i++) {
        printf("  %s\n", test_unit[i].name);
    }
}

// static int get_input(void) {
//     int ret = 0;
//     uint8_t i = 0;
//     char input[32];

//     printf("\n===== UNIT 测试程序 =====\n");
//     printf("请选择测试项 (输入数字):\n");
//     for (i = 0; i < TEST_UNIT_NUM; i++) {
//         printf("%s\n", test_unit[i].text);
//     }
//     printf("\n请输入选择: ");
//     if (fgets(input, sizeof(input), stdin) == NULL) {
//         return -1;
//     }
//     ret = atoi(input);

//     return ret;
// }

int main(int argc, char *argv[])
{
    int ret = 0;
    uint8_t i = 0;
    struct sigaction sa;
    sa.sa_handler = handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    init_test_unit(test_unit);
    while (!exit_flag) {
        if (argc == 1) {
#if 0
            ret = get_input();
            if (ret == 0) {
                printf("程序退出。\n");
                break;
            } else if ((ret > 0) && (ret < TEST_UNIT_NUM)) {
                if (test_unit[ret].unit_test) {
                    test_unit[ret].unit_test(argc, argv);
                } else {
                    printf("测试项 %d 尚未实现！\n", ret);
                }
            } else {
                printf("无效选择，请重新输入！\n");
                continue;
            }
#else
            usage();
            return EXIT_FAILURE;
#endif
        } else {
            for (i = 1; i < TEST_UNIT_NUM; i++) {
                if (strcmp(argv[1], test_unit[i].name) == 0) {
                    test_unit[i].unit_test(argc, argv);
                    return EXIT_SUCCESS;
                }
            }
            if (i == TEST_UNIT_NUM) {
                usage();
                return EXIT_FAILURE;
            }
        }
    }

    return ret;
}
